package io.github.wanggit.antrpc.client.spring.utils;

import io.github.wanggit.antrpc.client.spring.CglibMethodInterceptor;
import org.springframework.lang.Nullable;

import java.util.Objects;


public abstract class StackTraceUtil {

    /**
     * The CGLIB class separator: {@code "$$"}.
     */
    public static final String CGLIB_CLASS_SEPARATOR = "$$";

    private StackTraceUtil() {
        throw new IllegalStateException();
    }

    public static String getRealPreviousStackTraceElement(StackTraceElement[] stackTraceElements) {
        for (StackTraceElement stackTraceElement : stackTraceElements) {
            if (!Objects.equals(stackTraceElement.getClassName(), Thread.class.getName())
                    && !Objects.equals(
                    stackTraceElement.getClassName(),
                    CglibMethodInterceptor.class.getName())
                    && !isCglibProxyClassName(stackTraceElement.getClassName())) {
                return stackTraceElement.toString();
            }
        }
        return null;
    }

    public static String max100LevelStackTraceElementsToString(
            StackTraceElement[] stackTraceElements) {
        int cnt = 0;
        StringBuilder builder = new StringBuilder();
        for (StackTraceElement stackTraceElement : stackTraceElements) {
            builder.append(stackTraceElement.toString()).append(System.lineSeparator());
            cnt++;
            if (cnt >= 100) {
                break;
            }
        }
        return builder.toString();
    }

    public static boolean isCglibProxyClassName(@Nullable String className) {
        return (className != null && className.contains(CGLIB_CLASS_SEPARATOR));
    }
}
